#include "TorusMesh.h"
#include "ObjMesh.h"
#include "TriangleList.h"
#define _USE_MATH_DEFINES
#include "math.h"

TorusMesh::TorusMesh(float radius1, float radius2, int segments, int sides):
Mesh(MESH_TRIANGLES,MESH_COLOR),
m_Radius1(radius1),
m_Radius2(radius2),
m_Segments(segments),
m_Sides(sides),
m_pMesh(0)
{
	CreateMesh();
}

TorusMesh::~TorusMesh(void)
{
}

void TorusMesh::CreateMesh()
{
	VertexList* vertexList = VertexList::Create3DPosColorVL(m_Sides*m_Segments);
	float tubeRadius = (m_Radius1 + m_Radius2)/2;
	float centerRadius = m_Radius1 + tubeRadius;
	int index = 0;
	DAEFloat3 position;

	TriangleList* triList = NULL;
	LineList* lineList = NULL;

	if ( this->CreateTriangles () )
		triList = new TriangleList( m_Sides*m_Segments*2 );
	if ( this->CreateLines() )
		lineList = new LineList(m_Segments* m_Sides*2);

	for (int i =0 ; i < m_Segments; ++i )
	{
		float angle = (float)(2 * i * M_PI / m_Segments);
		float xaxis = cos(angle);
		float yaxis = sin(angle);
		
		float xpos = centerRadius * xaxis;
		float ypos = centerRadius * yaxis;

		for ( int inner = 0 ;  inner < m_Sides; ++inner )
		{
			float tubeAngle = (float)( 2 * inner * M_PI / m_Sides);
			float tubex = tubeRadius * cos(tubeAngle);
			float tubey = tubeRadius * sin(tubeAngle);

			float x = xpos + tubex * xaxis;
			float y = ypos + tubex * yaxis;
			float z = tubey ;
			position.SetValues(x,y,z);
			int index1 = index;
			int index2 = index1+1;
			if ( index2 % m_Sides == 0 )
				index2 -= m_Sides;
			int index3 = (index + m_Sides) % (m_Sides*m_Segments);

			int index4 = index3 + 1;
			if ( index4 % m_Sides == 0 )
				index4 -= m_Sides;
			
			if ( this->CreateLines() ){
				lineList->AddIndexedLine( index1, index2 );
				lineList->AddIndexedLine(index1 , index3 );
			}
			if  (this->CreateTriangles() )
			{
				triList->AddIndexedFace(index1,index3,index2);
				triList->AddIndexedFace(index2,index3,index4);
			}
			vertexList->AddVertexData(index++,POSITION,&position);
		}
	}
	DAEFloat3 color(1,1,1);
	vertexList->FillSemantic(COLOR,&color);
	if ( this->CreateTriangles() )
	{
		m_pMesh = new ObjMesh(vertexList,triList);
		if  (this->CreateLines() ){
			IndexBufferMaterial* ibm = new IndexBufferMaterial(lineList);
			m_pMesh->AddIndexBuffer(ibm);
		}
	}else if ( this->CreateLines() )
	{
		m_pMesh = new ObjMesh(vertexList,lineList);
	}
}
